package com.pig4cloud.pig.iotData.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.amazonaws.services.s3.model.S3Object;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.file.core.FileProperties;
import com.pig4cloud.pig.common.file.core.FileTemplate;
import com.pig4cloud.pig.iot.entity.IotDeviceMessageEntity;
import com.pig4cloud.pig.iot.mapper.IotDeviceMessageMapper;
import com.pig4cloud.pig.iotData.constant.IotDataKgBotCamFileDetConstant;
import com.pig4cloud.pig.iotData.entity.IotDataKgbotcamFileEntity;
import com.pig4cloud.pig.iotData.mapper.IotDataKgbotcamFileMapper;
import com.pig4cloud.pig.iotData.properties.FanyuServerProperties;
import com.pig4cloud.pig.iotData.properties.YoloServerProperties;
import com.pig4cloud.pig.iotData.service.IotDataKgbotcamFileService;
import com.pig4cloud.pig.iotData.utils.ByteToMultipartFileUtil;
import com.pig4cloud.pig.iotData.utils.OkHttpUtil;
import com.pig4cloud.pig.iotData.utils.IotDataSecurityUtil;
import com.pig4cloud.plugin.websocket.config.WebSocketMessageSender;
import io.lettuce.core.AbstractRedisAsyncCommands;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.Headers;

/**
 * 多肉kgbotcam采集的图片文件管理表
 *
 * @author lty
 * @date 2024-11-07 22:24:12
 */
@Slf4j
@Service
@AllArgsConstructor
public class IotDataKgbotcamFileServiceImpl extends ServiceImpl<IotDataKgbotcamFileMapper, IotDataKgbotcamFileEntity> implements IotDataKgbotcamFileService {

	//	因为加了构造函数注解，所以会构造函数自动注入
	private final FileTemplate fileTemplate;

	private final FileProperties properties;



	/**
	 * 用户访问文件的路径开头
	 */
	private final String fileAccessUrl="/admin/duorouKgbotcamFile";

	/**
	 * 在bucketName下面的 相对保存目录
	 */
	private final String relativeDir="duorouKgBotCamDet";

	/**
	 * 在原始图片文件当前路径下 保存检测后图片的目录
	 */
	private final String detedDir="detected";

	private final YoloServerProperties yoloServerProperties;
	private final FanyuServerProperties fanyuServerProperties;

	private final ObjectMapper objectMapper;

	private IotDeviceMessageMapper iotDeviceMessageMapper;





	/**
	 * 上传文件
	 * @param file
	 * @return
	 */
	@Override
	public R uploadToDetectFile(MultipartFile file, IotDataKgbotcamFileEntity duorouKgbotcamFile) {
		String suffixName = FileUtil.extName(file.getOriginalFilename());
		suffixName=handleFileSuffixName(suffixName);

		String fileName = IdUtil.simpleUUID() + StrUtil.DOT + suffixName;
		Map<String, Object> resultMap = new HashMap<>(4);
		String bucketNameThis = properties.getBucketName()+'/'+relativeDir; //todo 为了和整个系统的bucketName区分开，原有本地bucket加上一个标识用于存储多肉的

		resultMap.put("bucketName", properties.getBucketName());
		resultMap.put("fileName", fileName);

		// 获取当前日期
		LocalDate currentDate = LocalDate.now();
		// 获取年、月、日
		int year = currentDate.getYear();
		int month = currentDate.getMonthValue();
		int day = currentDate.getDayOfMonth();
		// 拼接文件路径(带上年月日）
		String filePathDir = String.format("%s/%d/%02d/%02d",bucketNameThis, year, month, day);
		String fileUrl = String.format("%s/%s/%s",fileAccessUrl, filePathDir, fileName);
		resultMap.put("url", fileUrl);
		try (InputStream inputStream = file.getInputStream()) {
//			在 localtemplate即本地存储中 这个bucket理解为 文件相对路径就好 使用对象存储他就是存储而fileName才是 文件路径
			fileTemplate.putObject(filePathDir, fileName, inputStream, file.getContentType());
			// 文件管理数据记录,收集管理追踪文件
			IotDataKgbotcamFileEntity iotDataKgbotcamFileEntity = fileLog(file, suffixName, fileUrl,duorouKgbotcamFile.getIotDeviceId());
			resultMap.put("re", iotDataKgbotcamFileEntity);
		}
		catch (Exception e) {
			log.error("上传失败", e);
			return R.failed(e.getLocalizedMessage());
		}
		return R.ok(resultMap);
	}







	@Override
	@Transactional(isolation = Isolation.REPEATABLE_READ) //READ_UNCOMMITTED READ_COMMITTED 一般读取已提交 REPEATABLE_READ SERIALIZABLE 左边到右边越来越强
	public R uploadDetectedFile(MultipartFile file, Long duorouFileId) {
		IotDataKgbotcamFileEntity byId = this.getById(duorouFileId);
		String originalPath = byId.getFileName();
		String prefixToRemove=fileAccessUrl+"/";

		// 检查输入字符串是否包含前缀
		if (originalPath.startsWith(prefixToRemove)) {
			// 删除前缀
			String remainingPath = originalPath.substring(prefixToRemove.length());
			// 获取最后一个斜杠的位置
			int lastSlashIndex = remainingPath.lastIndexOf("/");

			// 提取文件路径（不包括最后的文件名）
			String origFileDirPath = remainingPath.substring(0, lastSlashIndex);

			// 提取文件名（包括扩展名）
//			String fileOrigName = remainingPath.substring(lastSlashIndex + 1);
			String fileOrigName = file.getOriginalFilename();

			String fileName=detedDir+"_"+fileOrigName;
			String filePathDir=origFileDirPath+"/"+detedDir;

			Map<String, String> resultMap = new HashMap<>(4);

			resultMap.put("bucketName", properties.getBucketName());
			resultMap.put("fileName", fileName);

			String fileUrl = String.format("%s/%s/%s",fileAccessUrl, filePathDir, fileName);
			resultMap.put("url", fileUrl);


			try (InputStream inputStream = file.getInputStream()) {
//			这个bucket理解为 文件相对路径就好
				fileTemplate.putObject(filePathDir, fileName, inputStream, file.getContentType());

				LambdaUpdateWrapper<IotDataKgbotcamFileEntity> updateWrapper = new LambdaUpdateWrapper<>();
				updateWrapper.eq(IotDataKgbotcamFileEntity::getId, byId.getId());  // 设置更新条件
				updateWrapper.set(IotDataKgbotcamFileEntity::getDetectedFileName, fileUrl);  // 设置需要更新的字段
				updateWrapper.set(IotDataKgbotcamFileEntity::getUpdateTime, LocalDateTime.now());
				updateWrapper.set(IotDataKgbotcamFileEntity::getUpdateBy, IotDataSecurityUtil.getUserName());
				// 文件管理数据记录,收集管理追踪文件 更新数据库 检测后的文件路径
				this.update(updateWrapper);
			} catch (Exception e) {
				log.error("上传失败", e);
				return R.failed(e.getLocalizedMessage());
			}
			return R.ok(resultMap);
		}
		// 输出结果

		return R.failed("路径错误");
	}



	/**
	 * 读取文件
	 * @param fileDir
	 * @param fileName
	 * @param response
	 */
	@Override
	public void getFile(String fileDir, String fileName, HttpServletResponse response) {
		try (S3Object s3Object = fileTemplate.getObject(fileDir, fileName)) {
//			response.setContentType("application/octet-stream; charset=UTF-8");
			// 获取文件的 MIME 类型
			String mimeType = getMimeType(fileName);
			response.setContentType(mimeType);
			// 设置 Content-Disposition 为 inline 以预览文件
			response.setHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
			IoUtil.copy(s3Object.getObjectContent(), response.getOutputStream());
		}
		catch (Exception e) {
			log.error("文件读取异常: {}", e.getLocalizedMessage());
		}
	}



	/**
	 * 删除文件
	 * @param id
	 * @return
	 */
	@Override
	@SneakyThrows
	@Transactional(rollbackFor = Exception.class)
	public Boolean deleteFile(Long id) {
		IotDataKgbotcamFileEntity byId = this.getById(id);
		if (Objects.isNull(byId)) {
			return Boolean.FALSE;
		}

		String originalPath = byId.getFileName();
		String prefixToRemove=fileAccessUrl+"/";

		// 检查输入字符串是否包含前缀
		if (originalPath.startsWith(prefixToRemove)) {
			// 删除前缀
			String remainingPath = originalPath.substring(prefixToRemove.length());
			// 获取最后一个斜杠的位置
			int lastSlashIndex = remainingPath.lastIndexOf("/");
			// 提取文件路径（不包括最后的文件名）
			String origFileDirPath = remainingPath.substring(0, lastSlashIndex);
			// 提取文件名（包括扩展名）
			String fileOrigName = remainingPath.substring(lastSlashIndex + 1);

			fileTemplate.removeObject(origFileDirPath, fileOrigName);
			return this.removeById(id);
		}else{
			log.error("删除的文件路径出错");
//			throw new RuntimeException("删除的文件路径出错");
			return this.removeById(id);
		}

//		return false;

	}




	/**
	 * 异步处理任务，这样调用图片检测的时候不会阻塞主线程里卖弄的任务
	 * @param entity
	//	 * @param iotDataKgbotcamFileEntity
	 */
	@Override
	@Async("duorouFileDetTaskExecutor")
	@Transactional(isolation = Isolation.REPEATABLE_READ)
	public void detDuoRouFileExecutor(IotDataKgbotcamFileEntity entity) {
		try {
			// ================= 第一步：病虫害检测 =================
			log.debug("开启病虫害检测任务 | 文件ID: {}", entity.getId());
			Response yoloResponse = OkHttpUtil.postJsonBody(
					yoloServerProperties.getBaseurl() + yoloServerProperties.getDetpath(),
					entity,
					null,
					60 * 3
			);
			log.debug("开始上传图片");
			String yoloImagePath = saveImage(yoloResponse, entity,"yolo");
			log.debug(yoloImagePath);
			processYoloResponse(yoloResponse, entity, yoloImagePath);

			// ================= 第二步：繁育检测 =================
			log.debug("开启繁育检测任务 | 文件ID: {}", entity.getId());
			Response fanyuResponse = OkHttpUtil.postJsonBody(
					fanyuServerProperties.getBaseurl() + fanyuServerProperties.getDetpath(),
					entity,
					null,
					60 * 3
			);
			String fanyuImagePath = saveImage(fanyuResponse, entity,"fanyu");
			processFanyuResponse(fanyuResponse, entity, fanyuImagePath);

		} catch (Exception e) {
			log.error("检测任务失败 | 文件ID: {} | 错误详情:", entity.getId(), e);
			Thread.currentThread().interrupt();
			throw new RuntimeException(e);
		}
	}

	// 保存图片的方法
	private String saveImage(Response response, IotDataKgbotcamFileEntity entity, String detectionType) throws Exception {
		try (Response res = response) {
			// 获取图片内容
			if (response.body() != null) {
				byte[] imageContent = response.body().bytes();
				System.out.println("Image content length: " + imageContent.length);
				// 将字节数组转换为 MultipartFile
				String orignfiedFileName = detectionType + "_" + entity.getOriginal();
				MultipartFile multipartFile = new ByteToMultipartFileUtil(imageContent, entity.getFileName(), orignfiedFileName, "image/" + entity.getType());
				R r = this.uploadDetectedFile(multipartFile, entity.getId());
				// 保存图片成功继续下一步，否则抛出错误
				if (r.getCode() == 0) {
					// 从 R 对象的 data 中获取图片保存路径
					if (r.getData() != null) {
						return r.getData().toString();
					} else {
						throw new Exception("保存图片成功，但返回结果中未包含图片路径");
					}
				} else {
					throw new Exception("保存检测后的图片失败，错误信息: ");
				}
			} else {
				throw new Exception("response.body()是null");
			}
		}
	}

	// ================= 病虫害响应处理 =================
	private void processYoloResponse(Response response, IotDataKgbotcamFileEntity entity, String imagePath) throws Exception {
		try (Response res = response) {
			// 基础校验
			if (response.body() == null) {
				throw new IOException("病虫害检测响应体为空");
			}

			// 处理报警和字段更新
			processDetectionResponse(
					response,
					entity,
					"BINGCHONG_ALARM",
					"unhealthy",
					imagePath
			);
		}
	}

	// ================= 繁育响应处理 =================
	private void processFanyuResponse(Response response, IotDataKgbotcamFileEntity entity, String imagePath) throws Exception {
		try (Response res = response) {
			// 基础校验
			if (response.body() == null) {
				throw new IOException("繁育检测响应体为空");
			}

			// 处理报警和字段更新
			processDetectionResponse(
					response,
					entity,
					"BEST_ALARM",
					"breed",
					imagePath
			);
		}
	}

	// ================= 通用响应处理 =================
	private void processDetectionResponse(
			Response response,
			IotDataKgbotcamFileEntity entity,
			String expectedMessageType,
			String triggerMessageDescribe,
			String imagePath
	) throws Exception {
		// 新增：从响应头中获取实际message_describe值
		String actualMessageDescribe = response.header("message_describe");

		log.debug("获取病虫监测响应");
		log.debug(actualMessageDescribe);

		// 条件判断：仅允许特定值插入报警
		if (!("unhealthy".equals(actualMessageDescribe) || "breed".equals(actualMessageDescribe))) {
			log.debug("跳过报警记录 | 不符合条件 message_describe={}", actualMessageDescribe);
			return;
		}

		log.debug("开始插入报警记录");

		// 解析detrejson字段（原逻辑保留）
		String detReJson = response.header("detrejson");
		JsonNode jsonNode = objectMapper.readTree(detReJson);

		// 新增：构建cap_img的JSON结构
		String detectedFileName = jsonNode.get("detectedFileName").asText();
		ObjectNode capImgNode = objectMapper.createObjectNode();
		capImgNode.put("cap_img", detectedFileName);

		// 修改后的报警记录插入
		insertAlarmMessage(
				entity,
				expectedMessageType,
				actualMessageDescribe, // 使用动态获取的值
				jsonNode.get("iotDeviceId").asLong(),
				imagePath, // 使用保存的图片路径
				jsonNode.get("createBy").asText(),
				jsonNode.get("updateBy").asText(),
				LocalDateTime.parse(jsonNode.get("createTime").asText(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
				LocalDateTime.parse(jsonNode.get("updateTime").asText(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
		);
		// 5. 更新文件检测状态
		updateFileDetectionStatus(entity, jsonNode);
	}

	// ================= 报警记录插入 =================
	private void insertAlarmMessage(
			IotDataKgbotcamFileEntity fileEntity,
			String messageType,
			String messageDescribe,
			Long devId,
			String detectedFileName,
			String createBy,
			String updateBy,
			LocalDateTime createTime,
			LocalDateTime updateTime
	) {
		IotDeviceMessageEntity alarm = new IotDeviceMessageEntity();
		// 从detrejson提取的字段
		alarm.setDevId(devId);
		alarm.setMessageSpecialInfo(detectedFileName); // 使用保存的图片路径
		alarm.setCreateBy(createBy);
		alarm.setUpdateBy(updateBy);
		alarm.setCreateTime(createTime);
		alarm.setUpdateTime(updateTime);

		// 报警核心字段
		alarm.setMessageType(messageType);

		// 根据messageDescribe的值设置不同的消息描述
		if ("breed".equals(messageDescribe)) {
			alarm.setMessageDescribe("经系统识别，此区域部分多肉植株生长很好，极大可能适用于制作生长繁育的叶片。");
		} else if ("unhealthy".equals(messageDescribe)) {
			alarm.setMessageDescribe("注意：经系统检测，此区域部分多肉可能出现病虫害，请及时处理！");
		} else {
			alarm.setMessageDescribe(messageDescribe);
		}

		alarm.setMessageStatement("0");
		sendWebSocketAlarm(alarm,detectedFileName);
		iotDeviceMessageMapper.insert(alarm);
		log.info("报警记录已插入 | 设备ID: {} | 类型: {}", devId, messageType);
	}
	// ================= WebSocket报警发送方法 =================
	private void sendWebSocketAlarm(IotDeviceMessageEntity alarm, String imagePath){
		try {
			// 1. 构建精简的消息内容（仅含 messageType 和 devId）
			String extractedUrl = extractUrlFromImagePath(imagePath);

			Map<String, Object> alarmMsg = new HashMap<>();
			alarmMsg.put("messageType", alarm.getMessageType());
			alarmMsg.put("devId", alarm.getDevId());
			alarmMsg.put("imageUrl", extractedUrl);
			alarmMsg.put("messageDescribe", alarm.getMessageDescribe());

			log.info(alarmMsg.toString());

			// 2. 将消息转换为JSON字符串
			ObjectMapper mapper = new ObjectMapper();
			String jsonMessage = mapper.writeValueAsString(alarmMsg);

			// 3. 通过WebSocket发送（使用原始send方法）
			WebSocketMessageSender.send("admin", jsonMessage);

			log.debug("WebSocket报警已发送 | 设备ID: {}", alarm.getDevId());
		} catch (Exception e) {
			log.error("WebSocket发送失败 | 设备ID: {} | 错误: {}",
					alarm.getDevId(), e.getMessage());
		}
	}

	// 新增方法：从imagePath中提取URL
	private String extractUrlFromImagePath(String imagePath) {
		// 使用正则表达式匹配url部分
		String regex = "url=([^,}]+)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(imagePath);

		if (matcher.find()) {
			return matcher.group(1);
		}
		log.warn("未找到有效的URL路径: {}", imagePath);
		return null;
	}

	// ================= 更新文件检测状态 =================
	private void updateFileDetectionStatus(IotDataKgbotcamFileEntity entity, JsonNode jsonNode) {
		// 从detrejson提取检测结果
		String predictStatus = jsonNode.get("predictStatus").asText();
		String detectedJson = jsonNode.get("detectedJson").asText();

		// 更新文件记录
		LambdaUpdateWrapper<IotDataKgbotcamFileEntity> wrapper = new LambdaUpdateWrapper<>();
		wrapper.eq(IotDataKgbotcamFileEntity::getId, entity.getId())
				.set(IotDataKgbotcamFileEntity::getPredictStatus, predictStatus)
				.set(IotDataKgbotcamFileEntity::getDetectedJson, detectedJson)
				.set(IotDataKgbotcamFileEntity::getUpdateTime, LocalDateTime.now())
				.set(IotDataKgbotcamFileEntity::getUpdateBy, "admin"); // 根据业务需求调整

		this.update(wrapper);
		log.debug("文件检测状态已更新 | 文件ID: {}", entity.getId());
	}

//	public void detDuoRouFileExecutor(IotDataKgbotcamFileEntity iotDataKgbotcamFileEntity) {
//		// 模拟文件处理任务
//		try {
//			log.debug("开启检测图片的任务");
//			String url=yoloServerProperties.getBaseurl()+yoloServerProperties.getDetpath();
//			log.debug(url);
//			Response response = OkHttpUtil.postJsonBody(url, iotDataKgbotcamFileEntity, null,60*3); //超时时间设置为3分钟
//			// 使用 try-with-resources 自动关闭 response
//			try (Response res = response) {
//				// 获取图片内容
//				if(response.body()!=null){
//					byte[] imageContent = response.body().bytes();
//					System.out.println("Image content length: " + imageContent.length);
//					// 将字节数组转换为 MultipartFile
//					MultipartFile multipartFile = new ByteToMultipartFileUtil(imageContent, iotDataKgbotcamFileEntity.getFileName(), iotDataKgbotcamFileEntity.getOriginal(), "image/"+ iotDataKgbotcamFileEntity.getType());
//					R r = this.uploadDetectedFile(multipartFile, iotDataKgbotcamFileEntity.getId());
//					//保存图片成功继续下一步，否则抛出错误
//					if(r.getCode()==0){
//						// 获取其他数据
//						String detReJson = response.header("detReJson");
//						IotDataKgbotcamFileEntity iotDataKgbotcamFileEntityDet = objectMapper.readValue(detReJson, IotDataKgbotcamFileEntity.class);
//
//						LambdaUpdateWrapper<IotDataKgbotcamFileEntity> updateWrapper = new LambdaUpdateWrapper<>();
//						updateWrapper.eq(IotDataKgbotcamFileEntity::getId, iotDataKgbotcamFileEntity.getId());  // 设置更新条件
//						updateWrapper.set(IotDataKgbotcamFileEntity::getPredictStatus, iotDataKgbotcamFileEntityDet.getPredictStatus());  // 设置需要更新的字段
//						updateWrapper.set(IotDataKgbotcamFileEntity::getDetectedJson, iotDataKgbotcamFileEntityDet.getDetectedJson());
//						updateWrapper.set(IotDataKgbotcamFileEntity::getUpdateTime, LocalDateTime.now());
//						updateWrapper.set(IotDataKgbotcamFileEntity::getUpdateBy, IotDataSecurityUtil.getUserName());
//
//						// 文件管理数据记录,收集管理追踪文件 更新数据库 检测后的文件路径
//						this.update(updateWrapper);
//
//						System.out.println("Custom data: " + detReJson);
//					}else{
//						throw new Exception("保存检测后的图片失败");
//					}
//				}else{
//					throw new Exception("response.body()是null");
//				}
//
//			}
//		} catch (Exception e) {
//			Thread.currentThread().interrupt();
//			throw new RuntimeException(e);
//		}
//	}








	/**
	 * *******************下面的 一般不需要controller调用 不继承基类了*******************
	 */

	/**
	 * 文件管理数据记录,收集管理追踪文件
	 * @param file 上传文件格式
	 * @param fileUrl 文件url
	 */
	private IotDataKgbotcamFileEntity fileLog(MultipartFile file, String suffixname, String fileUrl, Long iotDeviceId) {
		IotDataKgbotcamFileEntity iotDataKgbotcamFileEntity = new IotDataKgbotcamFileEntity();
		iotDataKgbotcamFileEntity.setFileName(fileUrl);
		iotDataKgbotcamFileEntity.setOriginal(file.getOriginalFilename());
		iotDataKgbotcamFileEntity.setFileSize(file.getSize());
		iotDataKgbotcamFileEntity.setType(suffixname);
		iotDataKgbotcamFileEntity.setBucketName(properties.getBucketName());
		iotDataKgbotcamFileEntity.setPredictStatus(IotDataKgBotCamFileDetConstant.DUOROU_DET_STATUS_WAIT);
//		todo 设置所属设备ID字段
		iotDataKgbotcamFileEntity.setIotDeviceId(iotDeviceId);

		this.save(iotDataKgbotcamFileEntity);
		return iotDataKgbotcamFileEntity;
	}




	/**
	 * 对于yolov检测多肉病虫的图片格式 都转换为 jpeg 和png 不能有jpg
	 * @param name
	 * @return
	 */
	private String handleFileSuffixName(String name){
		if(name.equalsIgnoreCase("jpeg") || name.equalsIgnoreCase("png") ){
			return name.toLowerCase();
		}
		if(name.equalsIgnoreCase("jpg")){ //同义转换为jpeg 方便yolo处理
			return "jpeg";
		}
		throw new RuntimeException("不支持的图片格式");
	}


	private String getMimeType(String fileName) {
		// 根据文件扩展名获取 MIME 类型
		if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
			return "image/jpeg";
		} else if (fileName.endsWith(".png")) {
			return "image/png";
		} else if (fileName.endsWith(".gif")) {
			return "image/gif";
		} else if (fileName.endsWith(".pdf")) {
			return "application/pdf";
		} else {
			return "application/octet-stream; charset=UTF-8";
		}
	}




}